home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1990 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* i2scan.c */
- /* Level 2 token scanner (binary tokens) */
- #include "ghost.h"
- #include "arch.h"
- #include "errors.h"
- #include "alloc.h"
- #include "store.h"
- #include "stream.h"
- #include "i2btoken.h"
- #include "i2bseq.h"
- #include "i2num.h"
-
- /* Import the system and user name tables */
- extern ref system_names, user_names;
-
- /* Forward references */
- private int scan_binary_sequence(P2(stream *, ref *));
-
- /* Scan a binary token. Called from the main scanner */
- /* when it encounters an ASCII code 128 or above. */
- /****** THIS ROUTINE STILL NEEDS MANY EOF CHECKS ******/
- int
- scan_binary_token(register stream *s, ref *pref, char tcode)
- { int num_format, code;
- uint arg;
- switch ( tcode )
- {
- case bt_seq_IEEE_msb:
- s->num_format = num_msb + num_float_IEEE; goto bseq;
- case bt_seq_IEEE_lsb:
- s->num_format = num_lsb + num_float_IEEE; goto bseq;
- case bt_seq_native_msb:
- s->num_format = num_msb + num_float_native; goto bseq;
- case bt_seq_native_lsb:
- s->num_format = num_lsb + num_float_native;
- bseq: return scan_binary_sequence(s, pref);
- case bt_int32_msb:
- num_format = num_msb + num_int32; goto num;
- case bt_int32_lsb:
- num_format = num_lsb + num_int32; goto num;
- case bt_int16_msb:
- num_format = num_msb + num_int16; goto num;
- case bt_int16_lsb:
- num_format = num_lsb + num_int16; goto num;
- case bt_int8:
- make_int(pref, (sgetc(s) ^ 128) - 128);
- return 0;
- case bt_fixed:
- num_format = sgetc(s);
- if ( !num_is_valid(num_format) )
- return e_syntaxerror;
- goto num;
- case bt_float_IEEE_msb:
- num_format = num_msb + num_float_IEEE; goto num;
- case bt_float_IEEE_lsb:
- num_format = num_lsb + num_float_IEEE; goto num;
- case bt_float_native:
- num_format = num_float_native;
- num: s->num_format = num_format;
- code = sget_encoded_number(s, pref);
- switch ( code )
- {
- case t_integer: case t_real:
- r_set_type(pref, code);
- break;
- case t_null: return e_syntaxerror;
- default: return code;
- }
- return 0;
- case bt_boolean:
- arg = sgetc(s);
- if ( arg & ~1 ) return e_syntaxerror;
- make_bool(pref, arg);
- return 0;
- case bt_string_256:
- arg = sgetc(s); goto str;
- case bt_string_64k_msb:
- arg = sgetc(s); arg = (arg << 8) + sgetc(s); goto str;
- case bt_string_64k_lsb:
- arg = sgetc(s) << 8; arg += sgetc(s);
- str: { byte *str = alloc(arg, 1, "string token");
- uint rcnt;
- if ( str == 0 ) return e_VMerror;
- rcnt = sread(s, str, arg);
- if ( rcnt != arg) return e_syntaxerror;
- make_tasv(pref, t_string, a_all, arg, bytes, str);
- } return 0;
- case bt_litname_system:
- *pref = system_names.value.refs[sgetc(s)]; return 0;
- case bt_execname_system:
- *pref = system_names.value.refs[sgetc(s)];
- xname: r_set_attrs(pref, a_executable);
- return 0;
- case bt_litname_user:
- *pref = user_names.value.refs[sgetc(s)]; return 0;
- case bt_execname_user:
- *pref = user_names.value.refs[sgetc(s)]; goto xname;
- case bt_num_array:
- { ref *nap;
- uint i;
- num_format = sgetc(s);
- if ( !num_is_valid(num_format) ) return e_syntaxerror;
- s->num_format = num_format;
- sgetshort(s, (short *)&arg);
- nap = (ref *)alloc(arg, sizeof(ref), "number array token");
- if ( nap == 0 ) return e_VMerror;
- for ( i = 0; i < arg; i++ )
- { ref *np = nap + i;
- int code = sget_encoded_number(s, np);
- switch ( code )
- {
- case t_integer: case t_real:
- r_set_type(np, code);
- break;
- case t_null: return e_syntaxerror;
- default: return code;
- }
- }
- make_tasv(pref, t_array, a_all, arg, refs, nap);
- } return 0;
- }
- return e_syntaxerror;
- }
-
- /* Scan a binary object sequence. */
- private int
- scan_binary_sequence(register stream *s, ref *pref)
- { uint top_size = sgetc(s);
- ushort size;
- uint max_array_index = top_size * sizeof(ref);
- uint min_string_index = 0xffff;
- byte *obj;
- uint index;
- #if big_endian
- # define must_swap_bytes num_is_lsb(s->num_format)
- #else
- # define must_swap_bytes !num_is_lsb(s->num_format)
- #endif
- sgetshort(s, (short *)&size);
- obj = alloc(1, size, "binary sequence token");
- if ( obj == 0 ) return e_VMerror;
- if ( sread(s, obj, size) != size ) return e_syntaxerror;
- /* Convert embedded refs */
- for ( index = 0; index < max_array_index;
- index += sizeof(bin_seq_obj)
- )
- { ref *ap = (ref *)obj + index;
- bin_seq_obj ob;
- byte bt;
- ob = *(bin_seq_obj *)ap;
- #define swap_size()\
- if ( must_swap_bytes )\
- bt = ob.size.b[0], ob.size.b[0] = ob.size.b[1], ob.size.b[1] = bt
- #define swap_value()\
- if ( must_swap_bytes )\
- bt = ob.value.b[0], ob.value.b[0] = ob.value.b[3], ob.value.b[3] = bt,\
- bt = ob.value.b[1], ob.value.b[1] = ob.value.b[2], ob.value.b[2] = bt
- switch ( ob.tx & 0x7f )
- {
- case bs_null:
- make_null(ap); break;
- case bs_integer:
- swap_value();
- make_int(ap, ob.value.w);
- break;
- case bs_real:
- swap_value();
- /****** DON'T HANDLE NON-NATIVE REAL YET ******/
- make_real(ap, ob.value.f);
- break;
- case bs_boolean:
- swap_value();
- make_bool(ap, (ob.value.w == 0 ? 0 : 1));
- break;
- case bs_string:
- swap_size(); swap_value();
- if ( ob.value.w < max_array_index ||
- ob.value.w + ob.size.w > size
- )
- return e_syntaxerror;
- if ( ob.value.w < min_string_index )
- min_string_index = (uint)ob.value.w;
- make_tasv(pref, t_string, (ob.tx < 128 ? a_all :
- a_all + a_executable), ob.size.w,
- bytes, obj + ob.value.w);
- break;
- case bs_name:
- case bs_eval_name:
- swap_size(); swap_value();
- switch ( ob.size.w )
- {
- case 0:
- if ( (ulong)ob.value.w >= user_names.size )
- return e_syntaxerror;
- *ap = user_names.value.refs[ob.value.w];
- break;
- case 0xffff:
- if ( (ulong)ob.value.w >= system_names.size )
- return e_syntaxerror;
- *ap = system_names.value.refs[ob.value.w];
- break;
- default:
- if ( ob.value.w < max_array_index ||
- ob.value.w + ob.size.w > size
- )
- return e_syntaxerror;
- if ( ob.value.w < min_string_index )
- min_string_index = (uint)ob.value.w;
- name_ref(obj + ob.value.w, ob.size.w, ap, 0);
- }
- if ( (ob.tx & 0x7f) == bs_eval_name )
- /****** LOOK UP THE NAME ******/
- ;
- if ( ob.tx >= 128 ) r_set_attrs(ap, a_executable);
- break;
- case bs_array:
- swap_size(); swap_value();
- if ( ob.value.w + ob.size.w > min_string_index ||
- ob.value.w & (sizeof(bin_seq_obj) - 1)
- )
- return e_syntaxerror;
- max_array_index = max(max_array_index,
- ob.value.w + ob.size.w);
- make_tasv(ap, t_array, (ob.tx < 128 ? a_all :
- a_all + a_executable), ob.size.w,
- refs, (ref *)(obj + ob.value.w));
- break;
- case bs_mark:
- make_mark(ap); break;
- default:
- return e_syntaxerror;
- }
- }
- make_tasv(pref, t_array, a_all, top_size, refs, (ref *)obj);
- return 0;
- }
-